﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YRevitJig;

namespace YJKRevitDimension.DetailIndex.Jig
{
	internal class LineJig : XLineJig
	{
		public LineJig.Step ThisOperStep { get; set; }

		public double Distance { get; set; }

		public bool IsUseCustomAngle { get; set; }

		public double Angel { get; set; }

		public LineJig(UIDocument uiDoc, bool IfUseCustomAngle, double angle) : base(uiDoc)
		{
			this.Angel = angle;
			base.LineAngle = angle;
			this.IsUseCustomAngle = IfUseCustomAngle;
			if (this.IsUseCustomAngle)
			{
				base.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
				return;
			}
			base.ResetPoint = XUiJigBase.EResetPoint.eByAxis;
		}

		public override List<Curve> CreateCurves()
		{
			return new List<Curve>();
		}

		public new XYZ PickStartPoint(string strPrompt = "请确定直线起点：")
		{
			XYZ startPoint;
			try
			{
				base.JigStage = XLineJig.EStage.eStartPt;
				base.StartPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				base.JigStage = XLineJig.EStage.eNoOper;
				startPoint = base.StartPoint;
			}
			catch
			{
				base.JigStage = XLineJig.EStage.eNoOper;
				base.StartPoint = null;
				throw;
			}
			return startPoint;
		}

		public new XYZ GetResetPoint(XYZ ptBase, XYZ ptUser)
		{
			XYZ result = new XYZ();
			this.Distance = this.FeetToMM(Math.Abs(ptUser.Y - base.StartPoint.Y));
			this.resultLines = this.DrawSinglePipeMarkLines(ptBase, ptUser, this.Angel, this.IsUseCustomAngle, this.Distance, ref result);
			return result;
		}

		public XYZ PickElbowPoint(XYZ ptStart, string strPrompt = "请确定直线终点：")
		{
			XYZ endPoint;
			try
			{
				this.ThisOperStep = LineJig.Step.First;
				base.JigStage = XLineJig.EStage.eEndPt;
				base.StartPoint = ptStart;
				base.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				base.EndPoint = this.GetResetPoint(base.StartPoint, base.EndPoint);
				base.JigStage = XLineJig.EStage.eNoOper;
				endPoint = base.EndPoint;
			}
			catch
			{
				this.ThisOperStep = LineJig.Step.First;
				if (this.m_prompDlg == null || base.CmdEndType != XUiJigBase.ECmdEndType.eEnter)
				{
					base.EndPoint = null;
					base.JigStage = XLineJig.EStage.eNoOper;
					throw;
				}
				base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
				XYZ xyz = base.Client2Revit(this.m_ptCur);
				xyz = this.GetResetPoint(xyz, base.StartPoint);
				double num = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
				XYZ xyz2 = (xyz - base.StartPoint).Normalize();
				base.EndPoint = base.StartPoint + xyz2 * num;
				base.JigStage = XLineJig.EStage.eNoOper;
				endPoint = base.EndPoint;
			}
			return endPoint;
		}

		public new XYZ PickEndPoint(XYZ ptStart, string strPrompt = "请确定直线终点：")
		{
			XYZ xyz = new XYZ();
			base.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
			this.Angel = 0.0;
			XYZ result;
			try
			{
				this.ThisOperStep = LineJig.Step.Second;
				base.JigStage = XLineJig.EStage.eEndPt;
				base.StartPoint = ptStart;
				base.ResetPoint = XUiJigBase.EResetPoint.eByAngle;
				base.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				base.EndPoint = this.GetResetPoint(base.StartPoint, base.EndPoint);
				base.JigStage = XLineJig.EStage.eNoOper;
				result = xyz;
			}
			catch
			{
				this.ThisOperStep = LineJig.Step.Second;
				if (this.m_prompDlg == null || base.CmdEndType != XUiJigBase.ECmdEndType.eEnter)
				{
					base.EndPoint = null;
					base.JigStage = XLineJig.EStage.eNoOper;
					throw;
				}
				base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
				XYZ xyz2 = base.Client2Revit(this.m_ptCur);
				double num = Convert.ToDouble(this.m_prompDlg.GetInputValue()) / 304.8;
				XYZ xyz3 = (xyz2 - base.StartPoint).Normalize();
				base.EndPoint = base.StartPoint + xyz3 * num;
				base.JigStage = XLineJig.EStage.eNoOper;
				result = base.EndPoint;
			}
			return result;
		}

		private double FeetToMM(double v)
		{
			return v * 304.8;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (!this.m_ptCur.IsEmpty && paintEventArgs != null)
			{
				try
				{
					LineJig.Step thisOperStep = this.ThisOperStep;
					if (thisOperStep != LineJig.Step.First)
					{
						if (thisOperStep != LineJig.Step.Second)
						{
							goto IL_2E1;
						}
					}
					else
					{
						this.resultLines.Clear();
						XYZ xyz = base.Client2Revit(this.m_ptCur);
						XYZ xyz2 = new XYZ(xyz.X, xyz.Y, base.StartPoint.Z);
						this.Distance = this.FeetToMM(Math.Abs(xyz2.Y - base.StartPoint.Y));
						XYZ xyz3 = null;
						if (!this.IsUseCustomAngle)
						{
							XYZ ptUser = base.Client2Revit(this.m_ptCur);
							if (base.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
							{
								xyz3 = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, base.StartPoint, this.Angel);
								this.m_ptCur = base.Revit2Client(xyz3);
							}
							else if (base.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
							{
								xyz3 = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, base.StartPoint);
								this.m_ptCur = base.Revit2Client(xyz3);
							}
							else if (base.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
							{
								xyz3 = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, base.StartPoint);
								if (xyz3 != null)
								{
									this.m_ptCur = base.Revit2Client(xyz3);
									base.DrawAxisLine(paintEventArgs.Graphics, base.StartPoint, xyz3);
									this.resultLines.Clear();
									this.resultLines.Add(YJKLineEx.YJKGetBound(base.StartPoint, xyz3));
								}
							}
							base.EndPoint = xyz3;
						}
						XGraphics g = new XGraphics(paintEventArgs.Graphics, base.JigPen);
						using (List<Line>.Enumerator enumerator = this.resultLines.GetEnumerator())
						{
							while (enumerator.MoveNext())
							{
								Line curve = enumerator.Current;
								new XLine2D(base.Revit2Client(curve.GetEndPoint(0)), base.Revit2Client(curve.GetEndPoint(1))).Draw(g);
							}
							goto IL_2E1;
						}
					}
					this.resultLines.Clear();
					XYZ xyz4 = base.Client2Revit(this.m_ptCur);
					XYZ xyz5 = new XYZ(xyz4.X, xyz4.Y, base.StartPoint.Z);
					this.Distance = this.FeetToMM(Math.Abs(xyz5.Y - base.StartPoint.Y));
					List<XCircle2D> list = new List<XCircle2D>();
					XGraphics g2 = new XGraphics(paintEventArgs.Graphics, base.JigPen);
					foreach (Line curve2 in this.resultLines)
					{
						new XLine2D(base.Revit2Client(curve2.GetEndPoint(0)), base.Revit2Client(curve2.GetEndPoint(1))).Draw(g2);
					}
					foreach (XCircle2D xcircle2D in list)
					{
						xcircle2D.Draw(g2);
					}
					IL_2E1:;
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
		}

		public List<Line> DrawSinglePipeMarkLines(XYZ pipePoint, XYZ location, double angle, bool isCustomAngle, double distance, ref XYZ endpoint)
		{
			List<Line> list = new List<Line>();
			try
			{
				double num = angle * Math.PI / 180.0;
				XYZ xyz = new XYZ(location.X, pipePoint.Y, pipePoint.Z);
				XYZ xyz2 = new XYZ(pipePoint.X, location.Y, pipePoint.Z);
				XYZ xyz3 = location - xyz2;
				XYZ xyz4 = location - xyz;
				if (isCustomAngle)
				{
					num = angle * Math.PI / 180.0;
				}
				else
				{
					num = Math.Asin(Math.Abs(location.Y - pipePoint.Y) / location.DistanceTo(pipePoint));
				}
				if (num > 0.0)
				{
					double num2 = AssistFunc.mmToFeet(distance) * Math.Tan(Math.PI*.5 - num);
					endpoint = pipePoint.Add(xyz3.Normalize() * num2).Add(xyz4.Normalize() * AssistFunc.mmToFeet(distance));
				}
				else
				{
					double num2 = location.X - pipePoint.X;
					endpoint = pipePoint.Add(base.UiDoc.ActiveView.RightDirection * num2);
				}
				list.Add(YJKLineEx.YJKGetBound(pipePoint, endpoint));
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return list;
		}

		public List<Line> DrawSinglePipeMarkLines(XYZ pipePoint, XYZ location, double angle, bool isCustomAngle, double distance, ref XYZ endpoint, double offset, double width, ref List<XCircle2D> circle2Ds)
		{
			new List<Line>();
			List<Line> list = this.DrawSinglePipeMarkLines(pipePoint, location, angle, isCustomAngle, distance, ref endpoint);
			list.AddRange(this.GetTextBoxLines(pipePoint, endpoint, offset, width));
			System.Drawing.Point ptCenter = default(System.Drawing.Point);
			if (endpoint.X - pipePoint.X < 0.0)
			{
				ptCenter = new System.Drawing.Point((int)((double)base.Revit2Client(endpoint).X - LineJig.m_CircleRadis * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), base.Revit2Client(endpoint).Y);
			}
			else
			{
				ptCenter = new System.Drawing.Point((int)((double)base.Revit2Client(endpoint).X + LineJig.m_CircleRadis * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), base.Revit2Client(endpoint).Y);
			}
			circle2Ds.Add(new XCircle2D(ptCenter, (int)(LineJig.m_CircleRadis * this.GetScale() * (double)base.UiDoc.ActiveView.Scale)));
			return list;
		}

		private List<Line> GetTextBoxLines(XYZ startpoint, XYZ endpoint, double offset, double width)
		{
			List<Line> list = new List<Line>();
			int num;
			if (endpoint.X - startpoint.X < 0.0)
			{
				num = -1;
			}
			else
			{
				num = 1;
			}
			System.Drawing.Point point = new System.Drawing.Point(base.Revit2Client(endpoint).X, (int)((double)base.Revit2Client(endpoint).Y + offset * this.GetScale() * (double)base.UiDoc.ActiveView.Scale));
			System.Drawing.Point point2 = new System.Drawing.Point((int)((double)point.X - (double)num * width * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), point.Y);
			System.Drawing.Point point3 = new System.Drawing.Point(point2.X, (int)((double)point2.Y - LineJig.m_TextBoxHeight * this.GetScale() * (double)base.UiDoc.ActiveView.Scale));
			System.Drawing.Point point4 = new System.Drawing.Point((int)((double)point3.X + (double)num * width * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), point3.Y);
			System.Drawing.Point point5 = point;
			list.Add(Line.CreateBound(base.Client2Revit(point2), base.Client2Revit(point3)));
			list.Add(Line.CreateBound(base.Client2Revit(point3), base.Client2Revit(point4)));
			list.Add(Line.CreateBound(base.Client2Revit(point4), base.Client2Revit(point5)));
			list.Add(Line.CreateBound(base.Client2Revit(point5), base.Client2Revit(point2)));
			System.Drawing.Point point6 = new System.Drawing.Point(base.Revit2Client(endpoint).X, (int)((double)base.Revit2Client(endpoint).Y - offset * this.GetScale() * (double)base.UiDoc.ActiveView.Scale));
			System.Drawing.Point point7 = new System.Drawing.Point((int)((double)point6.X - (double)num * width * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), point6.Y);
			System.Drawing.Point point8 = new System.Drawing.Point(point7.X, (int)((double)point7.Y + LineJig.m_TextBoxHeight * this.GetScale() * (double)base.UiDoc.ActiveView.Scale));
			System.Drawing.Point point9 = new System.Drawing.Point((int)((double)point8.X + (double)num * width * this.GetScale() * (double)base.UiDoc.ActiveView.Scale), point8.Y);
			System.Drawing.Point point10 = point6;
			list.Add(Line.CreateBound(base.Client2Revit(point7), base.Client2Revit(point8)));
			list.Add(Line.CreateBound(base.Client2Revit(point8), base.Client2Revit(point9)));
			list.Add(Line.CreateBound(base.Client2Revit(point9), base.Client2Revit(point10)));
			list.Add(Line.CreateBound(base.Client2Revit(point10), base.Client2Revit(point7)));
			return list;
		}

		private double GetScale()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			RevitViewExtension.GetRevitWndRectangle(base.UiViewActive, ref num, ref num2, ref num3, ref num4);
			Transform inverse = base.ViewActive.CropBox.Transform.Inverse;
			IList<XYZ> zoomCorners = base.UiViewActive.GetZoomCorners();
			XYZ xyz = inverse.OfPoint(zoomCorners[0]);
			XYZ xyz2 = inverse.OfPoint(zoomCorners[1]);
			return (double)(num4 - num2) / (xyz2.Y - xyz.Y);
		}

		public List<Line> resultLines = new List<Line>();

		private static double m_CircleRadis = 0.016404199475065617;

		private static double m_TextBoxHeight = 0.016404199475065617;

		public const double _epsDouble = 1E-09;

		public enum Step
		{
			First,
			Second
		}
	}
}
